package org.swim.session;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.RemoteBinding;
import org.swim.entity.AddAbilityRequest;
import org.swim.entity.User;
import org.swim.entity.Ability;

@Stateless
@RemoteBinding(jndiBinding="UserManagerRemote")
public class UserManager implements UserManagerRemote {

	/**
	 * Manager degli entity beans. Permette di interagire direttamente col database inserendo e ricercando dati
	 */
	@PersistenceContext(unitName="swim") private EntityManager manager;
	
	@Override
	public void nominateAdmin(int userID) {
		
		User toNomine= new User();
		toNomine=manager.find(User.class, userID);
		
		toNomine.setAdmin(true);
		
	}

	@Override
	public void revokeAdmin(int userID) {
		User toNomine= new User();
		toNomine=manager.find(User.class, userID);
		
		toNomine.setAdmin(false);		
	}

	@Override
	public int changePassword(int userID, String newPass) {
		
		User toChange= new User();
		toChange=manager.find(User.class, userID);
		
		if(toChange.getPassword().equals(newPass))
			return -1;
		else
		{
			toChange.setPassword(newPass);
			return 0;
		}
	}
	
	@Override
	public void changeAvatar(int userID, String newAvatar) {	
		User toChange= new User();
		toChange=manager.find(User.class, userID);
		toChange.setAvatar(newAvatar);
	}

	@Override
	public int changeMail(int userID, String newMail) {
		
		User toChange= new User();
		toChange=manager.find(User.class, userID);
		
		if(toChange.getPassword().equals(newMail))
			return -1;
		else
		{
			toChange.setPassword(newMail);
			return 0;
		}
	}

	@Override
	public User getUser(int userID) {
		User toFind= new User();
		toFind=manager.find(User.class, userID);
		return toFind;
	}
	
	@Override
	public List<Ability> getAbilityListByID (int userID)
	{
		List<Ability> result = new ArrayList<Ability>();
		
		try 
		{
			User MITTENTE=manager.find(User.class, userID);

			Query q = manager.createQuery("SELECT OBJECT(ar) FROM AddAbilityRequest as ar" +
											" WHERE ar.mittente=:U AND ar.approvata=true");
			q.setParameter("U", MITTENTE);

			
			
			@SuppressWarnings("unchecked")
			Collection<AddAbilityRequest> coll = (Collection<AddAbilityRequest>) q.getResultList();

			Iterator<AddAbilityRequest> itar = coll.iterator();
			
			while (itar.hasNext())
			{	
				result.add(itar.next().getAbilita());
			}
			
		} 
		catch (EntityNotFoundException exc){} 
		
		return result;		
		
	}
	
	public List<Ability> getFriendListByID (int userID)
	{
		List<Ability> result = new ArrayList<Ability>();
		
		try 
		{
			Query q = manager.createQuery("SELECT OBJECT(Integer u) FROM FriendshipRequest as fr" +
											"WHERE fr.approvata=true AND ( (fr.getMittente()=:ID AND u=fr.getDestinatario()) " +
											"OR (fr.getDestinatario()=:ID AND u=fr.getMittente()) )");
			q.setParameter("ID", userID);
						
			@SuppressWarnings("unchecked")
			Collection<Ability> coll = (Collection<Ability>) q.getResultList();

			Iterator<Ability> itar = coll.iterator();
			
			while (itar.hasNext())
			{	
				result.add(itar.next());
			}
			
		} 
		catch (EntityNotFoundException exc){} 
		
		return result;		
	}
		
	public boolean existingAbilityRequest(int userID, int abilityID)
	{
		User MITTENTE=manager.find(User.class,userID);
		Ability ABILITY=manager.find(Ability.class,abilityID);

		try
		{
			Query q=manager.createQuery("SELECT OBJECT(ra) FROM AddAbilityRequest ra" +
										" WHERE ra.mittente=:MIT AND" +
										" ra.ability=:AB");
			
			q.setParameter("MIT", MITTENTE);
			q.setParameter("AB", ABILITY);
			
			Object ra=q.getSingleResult();
			
			if(ra==null)
			{
				return false;
			}

		}			
		catch (NoResultException e) {return false;}

		return true;
	}

}
